<?php

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of BATimerCooker
 *
 * @author jianfeng
 */
class BATimerCooker extends BCooker {

    //put your code here

    const Run_Frequency_OnceTillEnd = 'onceTillEnd';
    const Run_Frequency_OnceEachTimeSlot = 'onceEachTimeSlot';
    const Run_Frequency_repeatTillEnd = 'repeatTillEnd';

    /**
     * 这个函数将函数（静态函数）加入一个列表，并设置运行开始时间和结束时间，
     * 在指定的时间区间内，函数将运行
     * 指定运行区间有2种方式，一种就是指定开始和结束时间，一种就是指定一个时间端，然后指定重复次数
     * 
     * @param type $function
     * @param type runFrequency, 3种方式运行函数，onceTillEnd(只运行一次），runEachTimeSlot（每个时间段一次），repeatTillEnd
     * (一直运行），默认是只运行一次
     * @param type $startTime, INTEGER FOR TIME
     * @param type $timeInterval, MUST BE INTEGER STAND FOR TIME INTERVAL
     * @param type $repeat, INTEGER, STAND FOR REPEAT TIMES
     * @param type $endTime
     * @param type $params
     */
    public function addTimerFunction($function, $startTime, $endTime = NULL, $runFrequency = 'onceTillEnd', $timeSlot, $repeat = NULL, $params = array()) {

        if ($runFrequency == NULL) {
            $runFrequency = self::Run_Frequency_OnceTillEnd;
        }
        $timerTable = new BAEventSheet('timerEvent');

        $itemData = array(
            'timeSlot' => $timeSlot,
            'startTime' => $startTime,
            'function' => $function,
            'runFrequency' => $runFrequency
        );
        if ($endTime != NULL) {
            $itemData['endTime'] = $endTime;
        }

        if ($repeat == NULL) {
            $theRepeat = 1;
        }

        if ($params != NULL) {
            $itemData['params'] = json_encode($params);
        }

        if ($repeat != NULL) {
            $itemData['repeat'] = $repeat;
            $theRepeat = $repeat;
        }

        if ($theRepeat != NULL) {
            //根据重复次数重新计算结束时间，如果设置了结束时间，设置结束时间到上次的
            //重复结束
            for ($i = 1; $i <= $theRepeat; $i++) {
                $theEndTime = $startTime + $timeSlot * $i;
                if ($endTime != NULL && $theEndTime > $endTime) {
                    break;
                } else {
                    $itemData['endTime'] = $theEndTime;
                }
            }
        }

        $list = $timerTable->getList(array('itemData' => $itemData));
        if ($list == NULL) {
            $timerTable->addList($itemData);
        }
    }

    public function runTimerFunctions() {

        $currentTime = time();

        $itemData = array(
            'startTime' => '<=' . $currentTime,
            'endTime' => '>' . $currentTime
        );

        $timerTable = new BAEventSheet('timer');
        $timerView = $timerTable->getView(array('itemData' => $itemData));

        $result = array();
        foreach ($timerView as $timerEvent) {
            $startTime = $timerEvent->getItem('startTime')->getValue();
            $timeInterval = $timerEvent->getItem('timeInterval')->getValue();
            $lastTimeSlot = $timerEvent->getItem('lastTimeSlot')->getValue();
            $currentTimeSlot = floor(($currentTime - $startTime) / $timeInterval);
            if ($currentTimeSlot > $lastTimeSlot) {
                $function = $timerEvent->getItem('function');
                $timerEvent->addItem('lastTimeSlot', $currentTimeSlot);
                if ($timerEvent->getItem('params') != NULL) {
                    $params = $timerEvent->getItem('params')->getValue();
                    $params = json_decode($params);
                    $function($params);
                } else {
                    $function();
                }
                $result[$function] = 'run successfully on timeSlot' . $currentTimeSlot;
            }
        }

        return $result;
    }

    /**
     * 这个函数将string的时间转换成数字时间，并且根据时间段计算出起始时间和最后时间
     * @param type $timeData
     * @return array, format: array('startTime'=>...,'endTime'=>...,,'timeSlotUnit'=>...,
     * 'timeSlotCount'=>....
     */
    public static function populateTimePeriod($timeData) {

        $startTime = NULL;
        $endTime = NULL;
        $timeSlotUnit = NULL;
        $timeSlotLength = NULL;
        $timeSlot = NULL;
        $timeSlotCount = NULL;
        $tStartTime = NULL;
        $tEndTime = NULL;

        $retPeriod = array();

        if (isset($timeData['startTime'])) {
            $startTime = $timeData['startTime'];
        }

        if (isset($timeData['endTime'])) {
            $endTime = $timeData['endTime'];
        }

        if (isset($timeData['timeSlotLength'])) {
            $timeSlotLength = $timeData['timeSlotLength'];
        } else {
            $timeSlotLength = 1;
        }

        if (isset($timeData['timeSlotUnit'])) {
            $timeSlotUnit = $timeData['timeSlotUnit'];
        }

        if ($timeSlotUnit != NULL) {
            if ($timeSlotLength > 1) {
                $timeSlot = $timeSlotLength . ' ' . $timeSlotUnit;
            } else {
                $timeSlot = $timeSlotLength . ' ' . $timeSlotUnit . 's';
            }
            $timeData['timeSlot'] = $timeSlot;
        }


        if (isset($timeData['timeSlotCount'])) {
            $timeSlotCount = $timeData['timeSlotCount'];
        }

        if ($startTime != NULL) {
            if (strtolower($startTime) == 'now') {
                $tStartTime = time();
                $retPeriod['startTime'] = $tStartTime;
            } else {
                $tStartTime = strtotime($startTime);
                $retPeriod['startTime'] = $tStartTime;
            }
        }

        if ($endTime != NULL) {
            if (strtolower($endTime) == 'now') {
                $tEndTime = time();
                $retPeriod['endTime'] = $tEndTime;
            } else {
                $tEndTime = strtotime($endTime);
                $retPeriod['endTime'] = $tEndTime;
            }
        }

        if ($tStartTime != NULL && $tEndTime == NULL) {

            if ($timeSlotCount == NULL) {
                $timeSlotCount = 1;
            } else {
                $retPeriod['timeSlotCount'] = $timeSlotCount;
            }

            if ($timeSlotUnit != NULL) {
                $pEndTime = $tStartTime;
                for ($i = 1; $i <= $timeSlotCount; $i++) {
                    $pEndTime = strtotime('+ ' . $timeSlot, $pEndTime);
                    if (!isset($retPeriod['timeSlotUnit'])) {
                        $retPeriod['timeSlotUnit'] = ($pEndTime - $tStartTime) / $timeSlotLength;
                        $retPeriod['timeSlot'] = $pEndTime - $tStartTime;
                        $retPeriod['timeSlotLength'] = $timeSlotLength;
                    }
                }
                $retPeriod['endTime'] = $pEndTime;
            }
        }

        if ($tEndTime != NULL && $tStartTime == NULL) {

            if ($timeSlotCount == NULL) {
                $timeSlotCount = 1;
            }

            if ($timeSlotUnit != NULL) {
                $pStartTime = $tEndTime;
                for ($i = 1; $i <= $timeSlotCount; $i++) {
                    $pStartTime = strtotime('- ' . $timeSlot, $pStartTime);
                    if (!isset($retPeriod['timeSlotUnit'])) {
                        $retPeriod['timeSlotUnit'] = ($tEndTime - $pStartTime) / $timeSlotLength;
                        $retPeriod['timeSlot'] = $tEndTime - $pStartTime;
                        $retPeriod['timeSlotLength'] = $timeSlotLength;
                    }
                }
                $retPeriod['startTime'] = $pStartTime;
            }
        }

        return $retPeriod;
    }

}
